<?php
/**
 * #Celebrate Shieh
 *             ,%%%%%%%%,
 *           ,%%/\%%%%/\%%
 *          ,%%%\c "" J/%%%
 * %.       %%%%/ o  o \%%%
 * `%%.     %%%%    _  |%%%
 *  `%%     `%%%%(__Y__)%%'
 *  //       ;%%%%`\-/%%%'
 * ((       /  `%%%%%%%'
 *  \\    .'          |
 *   \\  /       \  | |
 *    \\/         ) | |
 *     \         /_ | |__
 *     (___________))))))) 攻城湿
 *
 *        _       _
 * __   _(_)_   _(_) __ _ _ __
 * \ \ / / \ \ / / |/ _` |'_ \
 *  \ V /| |\ V /| | (_| | | | |
 *   \_/ |_| \_/ |_|\__,_|_| |_|
 */

namespace App\Services;

use App\Libs\Email\EmailImap;
use app\Libs\Zip\Zip;
use App\Models\Common\FailedJob;
use App\Models\Expansion\Delete;
use App\Models\Expansion\EmailReceive;
use App\Models\Expansion\EmailSend;
use App\Models\System\EmailHair;
use App\Models\System\File;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class EmailService
{
    use Service;

    /**
     * 邮件管理首页
     *
     * @param Request $request
     *
     * @return mixed
     */
    public function EmailIndexService( $request )
    {
        if ( ! $request->filled('title') ) request()->offsetSet('title', 'EmailReceive');
        $title = $request->input('title');
        $name  = $request->input('name');
        if ( $title == 'EmailReceive' ) {
            $table            = 'email_receives';
            $email[ 'title' ] = '收件箱';
        }

        else {
            $table            = 'email_sends';
            $email[ 'title' ] = '发件箱';
        }
        $where             = function ( $query ) use ( $request, $name ) {
            if ( $name ) $query->where('title', 'like', "%" . $name . "%");
        };
        $data[ 'receive' ] = EmailReceive::CountModel();
        $data[ 'sends' ]   = EmailSend::CountModel();
        if ( $title == 'EmailReceive' ) $email = EmailReceive::PaginateModel($where, [
            'sender', 'name', 'title', 'status', 'id', 'file', 'created_at',
        ]);
        else $email = EmailSend::PaginateModel($where, [
            'id', 'sender', 'name', 'receipt', 'title', 'created_at', 'file',
        ]);
        request()->offsetSet('table', $table);
        $email->appends([
            'title' => $title,
            'name'  => $name,
            'table' => $table,
        ])->render();
        return view('expansion.email.index', compact('data', 'email', 'request'));
    }

    /**
     * 查看邮件详情
     *
     * @param Request $request
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
     */
    public function EmailShowService( $request )
    {
        $where   = function ( $query ) use ( $request ) {
            $query->where('id', $request->input('id'));
        };
        $storage = $this->getStorage('public');
        if ( ! $request->filled('title') ) return back()->with('error', $this->getErrorCode()::message(1001));
        if ( $request->input('title') == 'EmailReceive' ) {
            $select = [ 'sender', 'name', 'title', 'status', 'id', 'file', 'created_at', 'content', 'eid' ];
            $email  = EmailReceive::FirstModel($where, $select);//获取邮件
            if ( $email->eid && $email->status == 1 ) {
                $emil = EmailHair::FindModel([ 'username', 'password', 'server', 'port' ]);//获取邮箱配置
                $user = $emil->username ? : config('app.username');
                $pass = $emil->password ? : config('app.password');
                $host = $emil->server ? : config('app.host');
                $port = $emil->port ? : config('app.port');
                set_time_limit(0);
                $mail    = new EmailImap();
                $connect = $mail->mailConnect($user, $pass, $host, $port);//连接邮箱
                if ( $connect ) {
                    $totalCount = $mail->mailTotalCount();//获取邮件总数
                    for ( $i = $totalCount; $i > 0; $i-- ) {//循环
                        $mailHeader = $mail->mailHeader($i);//获取邮件标题
                        if ( $mailHeader != [] ) {
                            if ( trim($mailHeader[ 'id' ]) == $email->eid && $mailHeader[ 'seen' ] == 'U' ) {//更改已读
                                $mail->mailRead($i);//已读
                                EmailReceive::UpdateModel($email->id, [ 'status' => 2 ]);
                            }
                        }
                    }
                    $mail->closeMail();//关闭
                }
            }
            $url        = 'email/email-' . $email->id . '.html';
            $email->url = $storage->url($url);
        }
        else {
            $email = EmailSend::FirstModel($where, [
                'id', 'sender', 'name', 'receipt', 'title', 'content', 'created_at', 'file',
            ]);
            $url   = 'email-send/email-' . $email->id . '.html';
            $data  = '<style>pre {
            margin: 10px 0;
            padding: 10px;
            line-height: 20px;
            border: 1px solid #ddd;
            border-left-width: 6px;
            background-color: #F2F2F2;
            color: #333;
            font-family: Courier New;
            font-size: 12px;
        }</style>';
            $storage->append($url, $data);
            $email->url = $storage->url($url);
        }
        $file = [];
        foreach ( explode(',', $email->file) as $key => $value ) {
            $file[ $key ] = File::FindModel($value);
            if ( ! $file[ $key ] ) unset($file[ $key ]);
        }
        return view('expansion.email.show', compact('email', 'request', 'file'));
    }

    /**
     * 邮件查询分组
     *
     * @return mixed
     */
    public function EmailCreateService()
    {
        $name = File::SelectGetModel('ext', 'ext');
        return view('expansion.email.create', compact('name'));

    }

    /**
     * 邮件发送
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function EmailUpdateService( $request )
    {
        set_time_limit(0);
        $validator = $this->getAdminValidator()->EmailStoreValidator($request);
        if ( $validator->first() ) return back()->with('error', $validator->first());
        $data[ 'name' ]    = $request->input('title');
        $data[ 'email' ]   = $request->input('name');
        $data[ 'content' ] = $request->input('content');
        $fileName          = [];
        if ( $request->filled('emailFile') ) {
            foreach ( $request->input('emailFile') as $value ) $fileName[] = File::FirstModel($value, [
                'id', 'name', 'url',
            ]);
            $data[ 'file' ]  = $fileName;
            $data1[ 'file' ] = implode(',', $request->input('emailFile'));
        }
        $data[ 'id' ] = TRUE;
        $key          = 'queues:default:reserved';
        $value        = json_encode($data);
        FailedJob::CreateModel([ 'key' => $key, 'content' => $value ]);
        $date                  = Carbon::now();
        $data1[ 'sender' ]     = EmailHair::ValueModel('sender');
        $data1[ 'receipt' ]    = $request->input('name');
        $data1[ 'name' ]       = EmailHair::ValueModel('name');
        $data1[ 'title' ]      = $data[ 'name' ];
        $data1[ 'created_at' ] = $date;//获取当前时间
        $data1[ 'updated_at' ] = $date;
        $id                    = EmailSend::InsertGetIdModel($data1);
        $url                   = 'email-send/email-' . $id . '.html';
        $this->getStorage('public')->put($url, $data[ 'content' ]);
        return redirect(route('expansion.email.index'))->with('success', '发送成功');
    }

    /**
     * 邮件删除
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function EmailDestroyService( $request )
    {
        $error = $this->getErrorCode();
        if ( ! $request->filled('title') ) return back()->with('error', $error::message(1001));
        if ( $request->input('title') == 'EmailReceive' ) {
            $emil = EmailHair::FindModel([ 'username', 'password', 'server', 'port' ]);
            $user = $emil->username ? : config('app.username');
            $pass = $emil->password ? : config('app.password');
            $host = $emil->server ? : config('app.host');
            $port = $emil->port ? : config('app.port');
            set_time_limit(0);
            $mail    = new EmailImap();
            $connect = $mail->mailConnect($user, $pass, $host, $port);//连接邮箱
            if ( $connect ) {
                $totalCount = $mail->mailTotalCount();//获取邮件总数
                for ( $i = $totalCount; $i > 0; $i-- ) {
                    $mailHeader = $mail->mailHeader($i);//获取标题
                    if ( trim($mailHeader[ 'id' ]) == $request->input('m_id') ) {
                        $mail->mailDelete($i);//删除邮件
                        EmailReceive::DestroyModel($request->input('id'));
                        errorStorage('email', '"邮箱" : ' . $mailHeader[ 'from' ] . ' "标题" : ' . $mailHeader[ 'subject' ] . ' "名称" : ' . $mailHeader[ 'fromName' ], '删除邮件成功', 'success', '删除邮件');
                    }
                }
                $mail->closeMail();//关闭邮箱
            }
            return back()->with('success', $error::message(204));
        }
        else {
            EmailSend::DestroyModel($request->input('id'));
            return back()->with('success', $error::message(204));
        }
    }

    /**
     * 下载邮件附件
     *
     * @param Request $request
     *
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function EmailDownloadService( $request )
    {
        $file  = File::FindModel($request->input('id'), [
            'user', 'uid', 'id', 'category', 'ext', 'name', 'file_url',
        ]);//查询文件
        $title = $file->user . '/' . $file->uid . '/' . $file->category . '/' . $file->ext . '/' . $file->name;
        if ( ! $this->getStorage('public')->exists($title) ) return back()->with('error', $this->getErrorCode()::message(1016));
        return response()->download($file->file_url);
    }

    /**
     * 批量下载邮件附件
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function EmailAllDownloadService( $request )
    {
        $error = $this->getErrorCode();
        $disk  = $this->getStorage('storage');
        $user  = Auth::user();
        $disk->makeDirectory('download/email/' . $user->id . '/zip');
        $reduce_path = 'download/email/' . $user->id . '/zip/' . 'email-' . $request->input('id') . '.zip';//压缩包文件名
        if ( $disk->exists($reduce_path) ) return $disk->download($reduce_path);
        $id     = explode(',', $request->input('id'));//把id拆分成数组
        $select = [ 'id', 'file_url' ];
        $result = DB::transaction(function () use ( $request, $select, $id, $disk, $reduce_path, $error, $user ) {
            $arr = [];
            foreach ( $id as $value ) {//循环
                if ( ! $value ) continue;
                $file = File::FindModel($value, $select);
                if ( ! file_exists($file->file_url) ) continue;//获取文件是否存在
                $arr[] = $file->file_url;
            }
            if ( ! ( new Zip() )->createZip($disk->fileUrl($reduce_path), $arr) ) return back()->with('error', $error::message(1019));
            if ( ! $disk->exists($reduce_path) ) return back()->with('error', $error::message(1019));
            $del = Delete::GetModel([ 'name' => $reduce_path ], [ 'id' ]);
            if ( $del ) foreach ( $del as $value ) Delete::DestroyModel($value->id);
            $data[ 'name' ] = $reduce_path;
            $data[ 'uid' ]  = $user->id;
            $data[ 'size' ] = maxsize($disk->size($reduce_path));//计算大小
            Delete::CreateModel($data);//存入删除表，定时任务会执行删除
            return $disk->download($reduce_path);//下载
        });
        return $result;
    }


    /**
     * 查询附件
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function EmailPicFileService( Request $request )
    {
        $where  = function ( $query ) use ( $request ) {
            if ( $request->filled('ext') ) $query->where('ext', $request->input('ext'));
            $query->where('uid', Auth::id());
            if ( $request->input('name') ) $query->where('name', 'like', "%" . $request->input('name') . "%");
            $query->where('user', 'admin');
        };
        $select = [ 'id', 'url', 'file_url', 'name' ];
        $email  = File::PaginateModel($where, [], $select);
        foreach ( $email as $key => $value ) $email[ $key ][ 'url' ] = assetImage($value->url);
        return data($email);
    }

    /**
     * 拉取邮件
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function EmailLaZaRdService()
    {
        return $this->getCommon()->emailLaZaRd();
    }

}
